package structs.quantity;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Represents a quantity of books. Different quantities
 * are represented by different QuantityTypes. Contains
 * the quantity, the sale price, and the QuantityType. 
 * @author SJP
 *
 */
public class Quantity implements Comparable<Quantity>, Serializable{

	public static final String n = "New",
						cancel = "Cancelled",
						needed = "Needed",
						onHand = "On Hand",
						onOrder = "On Order",
						received = "Received",
						u = "Used",
						bba = "Buyback Available",
						bbp = "Buyback Purchase";
	
	public enum QuantityType {
		NEW_OO (onOrder,true), NEW_OH (onHand,true),
		NEW_N (needed,true), NEW_CAN (cancel,true),
		NEW_R (received,true), USED_OO (onOrder,false),
		USED_OH (onHand,false), USED_N (needed,false),
		USED_CAN (cancel,false), USED_R (received,false),
		USED_BBA (bba,false), USED_BBP (bbp,false);
		
		private String type;
		private boolean newStat;
		private double purchasePrice;
		private Location loc;
		
		/**
		 * Creates a new QuantityType with the given type, new/used, purchase price, and location
		 * @param t
		 * @param news
		 * @param pprice
		 * @param l
		 */
		QuantityType(String t, boolean news) {
			type = t;
			newStat = news;
		}
		
		/**
		 * @return the type of quantity
		 */
		public String getType() {return type;}
		
		/**
		 * @return the purchase price
		 */
		public double getPrice() {return purchasePrice;}
		
		/**
		 * Sets the purchase price and returns the new value.
		 * @param p new purchase price
		 * @return new purchase price
		 */
		public double setPrice(double p) {return purchasePrice = p;}
		
		/**
		 * @return true if quantity is new, else false.
		 */
		public boolean isNew() {return newStat;}
		
		/**
		 * @return the location of the book
		 */
		public Location getLocation() {return loc;}
		
		/**
		 * Sets the location and returns the new location.
		 * @param l new location
		 * @return new location
		 */
		public Location setLocation(Location l) { return loc = l;}
		
		public static QuantityType getQT(String t, boolean news) {
			switch (t) {
			case cancel: return getCAN(news);
			case needed: return getN(news);
			case onHand: return getOH(news);
			case onOrder: return getOO(news);
			case received: return getR(news);
			case bba: return getUBBA();
			case bbp: return getUBBP();
			default: return null;
			}
		}
		
		public static QuantityType getOO(boolean news){ return news? getNOO() : getUOO(); }
		public static QuantityType getOH(boolean news){ return news? getNOH() : getUOH(); }
		public static QuantityType getN(boolean news){ return news? getNN() : getUN(); }
		public static QuantityType getCAN(boolean news){ return news? getNCAN() : getUCAN(); }
		public static QuantityType getR(boolean news){ return news? getNR() : getUR(); }
		
		public static QuantityType getNOO() {return NEW_OO;}
		public static QuantityType getNOH() {return NEW_OH;}
		public static QuantityType getNN() {return NEW_N;}
		public static QuantityType getNCAN() {return NEW_CAN;}
		public static QuantityType getNR() {return NEW_R;}
		public static QuantityType getUOO() {return USED_OO;}
		public static QuantityType getUOH() {return USED_OH;}
		public static QuantityType getUN() {return USED_N;}
		public static QuantityType getUCAN() {return USED_CAN;}
		public static QuantityType getUR() {return USED_R;}
		public static QuantityType getUBBA() {return USED_BBA;}
		public static QuantityType getUBBP() {return USED_BBP;}
	}
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -8162622614488679058L;
	private int qty;
	private QuantityType type;

	/**
	 * Creates a new Quantity with the given quantity and QuantityType
	 * @param q
	 * @param t
	 */
	public Quantity(int q, QuantityType t) {
		qty = q;
		type = t;
	}
	
	/**
	 * @return quantity
	 */
	public int getQty() {return qty;}
	
	/**
	 * @return the type of quantity
	 */
	public QuantityType getType() {return type;}
	
	/**
	 * @return QuantityType qty.
	 */
	@Override
	public String toString() {return type.toString()+" "+qty;}

	@Override
	public int compareTo(Quantity q) {
		return type.compareTo(q.getType());
	}
	
	private void writeObject(ObjectOutputStream out) throws IOException {
		out.defaultWriteObject();
	}
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		in.defaultReadObject();
	}
	
}
